<?php
/**
 * @author    李梓钿
 *
 */
namespace oscshop;
class Dir {

	private $_values = array();
	public $error = "";

	/**
	  +----------------------------------------------------------
	 * 架构函数
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @param string $path  目录路径
	  +----------------------------------------------------------
	 */
	function __construct($path='./', $pattern = '*') {
		if (substr($path, -1) != "/") {
			$path .= "/";
		}
		$this->listFile($path, $pattern);
	}

	/**
	  +----------------------------------------------------------
	 * 取得目录下面的文件信息
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @param mixed $pathname 路径
	  +----------------------------------------------------------
	 */
	function listFile($pathname, $pattern = '*') {
		static $_listDirs = array();
		$guid = md5($pathname . $pattern);
		if (!isset($_listDirs[$guid])) {
			$dir = array();
			$list = glob($pathname . $pattern);
			foreach ($list as $i => $file) {
				//$dir[$i]['filename']    = basename($file);
				//basename取中文名出问题.改用此方法
				//编码转换.把中文的调整一下.
				$dir[$i]['filename'] = preg_replace('/^.+[\\\\\\/]/', '', $file);
				$dir[$i]['pathname'] = realpath($file);
				$dir[$i]['owner'] = fileowner($file);
				$dir[$i]['perms'] = fileperms($file);
				$dir[$i]['inode'] = fileinode($file);
				$dir[$i]['group'] = filegroup($file);
				$dir[$i]['path'] = dirname($file);
				$dir[$i]['atime'] = fileatime($file);
				$dir[$i]['ctime'] = filectime($file);
				$dir[$i]['size'] = filesize($file);
				$dir[$i]['type'] = filetype($file);
				$dir[$i]['ext'] = is_file($file) ? strtolower(substr(strrchr(basename($file), '.'), 1)) : '';
				$dir[$i]['mtime'] = filemtime($file);
				$dir[$i]['isDir'] = is_dir($file);
				$dir[$i]['isFile'] = is_file($file);
				$dir[$i]['isLink'] = is_link($file);
				//$dir[$i]['isExecutable']= function_exists('is_executable')?is_executable($file):'';
				$dir[$i]['isReadable'] = is_readable($file);
				$dir[$i]['isWritable'] = is_writable($file);
			}
			$cmp_func = create_function('$a,$b', '
			$k  =  "isDir";
			if($a[$k]  ==  $b[$k])  return  0;
			return  $a[$k]>$b[$k]?-1:1;
			');
			// 对结果排序 保证目录在前面
			usort($dir, $cmp_func);
			$this->_values = $dir;
			$_listDirs[$guid] = $dir;
		} else {
			$this->_values = $_listDirs[$guid];
		}
	}

	/**
	  +----------------------------------------------------------
	 * 返回数组中的当前元素（单元）
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return array
	  +----------------------------------------------------------
	 */
	function current($arr) {
		if (!is_array($arr)) {
			return false;
		}
		return current($arr);
	}

	/**
	  +----------------------------------------------------------
	 * 文件上次访问时间
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return integer
	  +----------------------------------------------------------
	 */
	function getATime() {
		$current = $this->current($this->_values);
		return $current['atime'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的 inode 修改时间
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return integer
	  +----------------------------------------------------------
	 */
	function getCTime() {
		$current = $this->current($this->_values);
		return $current['ctime'];
	}

	/**
	  +----------------------------------------------------------
	 * 遍历子目录文件信息
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return DirectoryIterator
	  +----------------------------------------------------------
	 */
	function getChildren() {
		$current = $this->current($this->_values);
		if ($current['isDir']) {
			return new Dir($current['pathname']);
		}
		return false;
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件名
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return string
	  +----------------------------------------------------------
	 */
	function getFilename() {
		$current = $this->current($this->_values);
		return $current['filename'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的组
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return integer
	  +----------------------------------------------------------
	 */
	function getGroup() {
		$current = $this->current($this->_values);
		return $current['group'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的 inode
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return integer
	  +----------------------------------------------------------
	 */
	function getInode() {
		$current = $this->current($this->_values);
		return $current['inode'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的上次修改时间
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return integer
	  +----------------------------------------------------------
	 */
	function getMTime() {
		$current = $this->current($this->_values);
		return $current['mtime'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的所有者
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return string
	  +----------------------------------------------------------
	 */
	function getOwner() {
		$current = $this->current($this->_values);
		return $current['owner'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件路径，不包括文件名
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return string
	  +----------------------------------------------------------
	 */
	function getPath() {
		$current = $this->current($this->_values);
		return $current['path'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的完整路径，包括文件名
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return string
	  +----------------------------------------------------------
	 */
	function getPathname() {
		$current = $this->current($this->_values);
		return $current['pathname'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的权限
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return integer
	  +----------------------------------------------------------
	 */
	function getPerms() {
		$current = $this->current($this->_values);
		return $current['perms'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件的大小
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return integer
	  +----------------------------------------------------------
	 */
	function getSize() {
		$current = $this->current($this->_values);
		return $current['size'];
	}

	/**
	  +----------------------------------------------------------
	 * 取得文件类型
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return string
	  +----------------------------------------------------------
	 */
	function getType() {
		$current = $this->current($this->_values);
		return $current['type'];
	}

	/**
	  +----------------------------------------------------------
	 * 是否为目录
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return boolen
	  +----------------------------------------------------------
	 */
	function isDir() {
		$current = $this->current($this->_values);
		return $current['isDir'];
	}

	/**
	  +----------------------------------------------------------
	 * 是否为文件
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return boolen
	  +----------------------------------------------------------
	 */
	function isFile() {
		$current = $this->current($this->_values);
		return $current['isFile'];
	}

	/**
	  +----------------------------------------------------------
	 * 文件是否为一个符号连接
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return boolen
	  +----------------------------------------------------------
	 */
	function isLink() {
		$current = $this->current($this->_values);
		return $current['isLink'];
	}

	/**
	  +----------------------------------------------------------
	 * 文件是否可以执行
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return boolen
	  +----------------------------------------------------------
	 */
	function isExecutable() {
		$current = $this->current($this->_values);
		return $current['isExecutable'];
	}

	/**
	  +----------------------------------------------------------
	 * 文件是否可读
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return boolen
	  +----------------------------------------------------------
	 */
	function isReadable() {
		$current = $this->current($this->_values);
		return $current['isReadable'];
	}

	/**
	  +----------------------------------------------------------
	 * 获取foreach的遍历方式
	  +----------------------------------------------------------
	 * @access public
	  +----------------------------------------------------------
	 * @return string
	  +----------------------------------------------------------
	 */
	function getIterator() {
		return new ArrayObject($this->_values);
	}

	// 返回目录的数组信息
	function toArray() {
		return $this->_values;
	}

	// 静态方法

	/**
	  +----------------------------------------------------------
	 * 判断目录是否为空
	  +----------------------------------------------------------
	 * @access static
	  +----------------------------------------------------------
	 * @return void
	  +----------------------------------------------------------
	 */
	function isEmpty($directory) {
		$handle = opendir($directory);
		while (($file = readdir($handle)) !== false) {
			if ($file != "." && $file != "..") {
				closedir($handle);
				return false;
			}
		}
		closedir($handle);
		return true;
	}

	/**
	  +----------------------------------------------------------
	 * 取得目录中的结构信息
	  +----------------------------------------------------------
	 * @access static
	  +----------------------------------------------------------
	 * @return void
	  +----------------------------------------------------------
	 */
	function getList($directory) {
		return scandir($directory);
	}

	/**
	  +----------------------------------------------------------
	 * 删除目录（包括下面的文件）
	  +----------------------------------------------------------
	 * @access static
	  +----------------------------------------------------------
	 * @return void
	  +----------------------------------------------------------
	 */
	function delDir($directory, $subdir = true) {
		if (is_dir($directory) == false) {
			$this->error = "该目录是不存在！";
			return false;
		}
		$handle = opendir($directory);
		while (($file = readdir($handle)) !== false) {
			if ($file != "." && $file != "..") {
				is_dir("$directory/$file") ?
						Dir::delDir("$directory/$file") :
						unlink("$directory/$file");
			}
		}
		if (readdir($handle) == false) {
			closedir($handle);
			rmdir($directory);
		}
	}

	/**
	  +----------------------------------------------------------
	 * 删除目录下面的所有文件，但不删除目录
	  +----------------------------------------------------------
	 * @access static
	  +----------------------------------------------------------
	 * @return void
	  +----------------------------------------------------------
	 */
	function del($directory) {
		if (is_dir($directory) == false) {
			$this->error = "该目录是不存在！";
			return false;
		}
		$handle = opendir($directory);
		while (($file = readdir($handle)) !== false) {
			if ($file != "." && $file != ".." && is_file("$directory/$file")) {
				unlink("$directory/$file");
			}
		}
		closedir($handle);
	}

	/**
	  +----------------------------------------------------------
	 * 复制目录
	  +----------------------------------------------------------
	 * @access static
	  +----------------------------------------------------------
	 * @return void
	  +----------------------------------------------------------
	 */
	function copyDir($source, $destination) {
		if (is_dir($source) == false) {
			$this->error = "源目录不存在！";
			return false;
		}
		if (is_dir($destination) == false) {
			mkdir($destination, 0700);
		}
		$handle = opendir($source);
		while (false !== ($file = readdir($handle))) {
			if ($file != "." && $file != "..") {
				is_dir("$source/$file") ?
						Dir::copyDir("$source/$file", "$destination/$file") :
						copy("$source/$file", "$destination/$file");
			}
		}
		closedir($handle);
	}

}
